#pragma once
#include <iostream>
#include <pthread.h>
#include <vector>
#include <string>
#include <queue>
#include <unistd.h>

using namespace std;

const int defaultnum = 3;
template <class T>
class ThreadPool
{
private:
    void Lockqueue()
    {
        pthread_mutex_lock(&_mutex);
    }
    void UnLockqueue()
    {
        pthread_mutex_unlock(&_mutex);
    }
    void ThreadSleep()
    {
        pthread_cond_wait(&_cond, &_mutex);
    }
    void ThreadWakeup()
    {
        pthread_cond_signal(&_cond);
    }
    void ThreadWakeAll()
    {
        pthread_cond_broadcast(&_cond);
    }

public:
    ThreadPool(int threadnum = defaultnum) : _threadnum(defaultnum), _waitnum(0), _isrunning(false)
    {
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }
    void HandlerTask(string name)
    {
        while (true)
        {
            // 1、保护队列
            Lockqueue();
            // 2、队列里不一定有资源
            if (_task_queue.empty() && _isrunning)//为空并且启动
            {
                _waitnum++;
                ThreadSleep();
                _waitnum--;
            }
            //如果为空并且线程退出
            if(_task_queue.empty() && !_isrunning)
            {
                UnLockqueue();
                cout << name << " quit..." <<endl;
                sleep(1);
                break;
            }
            // 获取任务
            T t = _task_queue.front();
            _task_queue.pop();
            UnLockqueue();

            // 处理任务，是线程独占的
            //t();
        }
    }

    void InitThreadPool()
    {
        for (int i = 0; i < _threadnum; i++)
        {
            string name = "thread-" + to_string(i + 1);
            _threads.emplace_back(bind(&ThreadPool::HandlerTask, this, placeholders::_1), name);
        }
    }

    void Start()
    {
        for (auto &thread : _threads)
        {
            thread.Start();
        }
        _isrunning = true;
    }
    void Stop()
    {
        Lockqueue();
        _isrunning = false;
        ThreadWakeAll();
        UnLockqueue();
    }
    void Wait()
    {
        for (auto &thread : _threads)
        {
            thread.Join();
        }
    }
    bool Enqueue(const T &t)
    {
        bool ret = false;
        Lockqueue();
        if (_isrunning)
        {
            _task_queue.push(t);
            if (_waitnum > 0)
            {
                ThreadWakeup();
            }
            ret = true;
        }
        UnLockqueue();
        return ret;
    }

    ~ThreadPool()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
    }

private:
    int _threadnum; // 线程的数量
    vector<yss::Thread> _threads;
    queue<T> _task_queue;
    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
    int _waitnum;
    bool _isrunning; // 判断线程是否启动
};